﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Xml.Serialization;
using System.Net;
using System.ComponentModel;
using System.Threading;
using Wintellect.PowerCollections;
using System.Text.RegularExpressions;
using TileDownLoader.Utils;
using TileDownLoader.Kml;
using TileDownLoader.Elevation;

namespace TileDownLoader
{
    public partial class MainWindow : Window
    {
        private BackgroundWorker m_gpxWorker = null;

        private void bttnUpdateElevation_Click(object sender, RoutedEventArgs e)
        {
            GpxFiles.LoadGpx();


            if (GpxFiles.GpxFile != null)
            {

                m_gpxWorker = new BackgroundWorker();

                m_gpxWorker.WorkerReportsProgress = true;
                m_gpxWorker.WorkerSupportsCancellation = true;

                ElevationSource selectedUpdateElevationSource = (ElevationSource)comboElevationUpdateSource.SelectedIndex;
                int selectedUpdateElevationType = comboElevationUpdateType.SelectedIndex;
                bool forceUpdate = !(bool)chkUpdateElevation.IsChecked;

                m_gpxWorker.DoWork += (senderLocal, eLocal) => 
                {

                    IElevation eleAlg = ElevationAlg.GetElevation(selectedUpdateElevationSource);
                    
                    if (selectedUpdateElevationType == 0)
                    {
                        eleAlg.UpdateElevationData(GpxFiles.GpxFile.wpt.ToList<dynamic>(), forceUpdate, "Elevation Data updated {0} of {1} points", m_gpxWorker);
                    }
                    else
                    {
                        for (int index = 0; index < GpxFiles.GpxFile.trk.Count; index++)
                        {
                            eleAlg.UpdateElevationData(GpxFiles.GpxFile.trk[index].trkseg.ToList<dynamic>(), forceUpdate,string.Format("Track {0} of {1}",index+1,GpxFiles.GpxFile.trk.Count) + " Elevation Data updated {0} of {1} points", m_gpxWorker);
                        }
                    }
                };

                m_gpxWorker.ProgressChanged += (senderLocal, eLocal) => {

                    txtElevationUpdateStatus.Content = eLocal.UserState as string;

                    progElevationUpdateStatus.Value = eLocal.ProgressPercentage;
                    
                
                };
                m_gpxWorker.RunWorkerCompleted += (senderLocal, eLocal) => 
                {
                    if (eLocal.Error != null)
                    {

                        MessageBox.Show(string.Format("Error:\r\n {0}", GetErrorMessage(eLocal.Error)), "Error");

                    }
                    else
                    {
                        MessageBox.Show("Update Completed.");

                        GpxFiles.SaveGpx();
                    }
                };

                m_gpxWorker.RunWorkerAsync();
            }
            else
            {
                MessageBox.Show("Error on opening file");
            }


        }

        private string GetErrorMessage(Exception ex)
        {
            StringBuilder retVal = new StringBuilder(ex.Message);

            if (ex.InnerException != null)
            {
                retVal.Append("\r\n");
                retVal.Append(GetErrorMessage(ex.InnerException));
            }
            return retVal.ToString();
        }
    }
}
